﻿using DataWasher.WebApi.EntitiesSQLServer;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace DataWasher.WebApi.Repositories.Base
{
    public class SqlserverRepositoryBase<TEntity> : IDisposable, ISqlserverRepositoryBase<TEntity> where TEntity : class
    {

        protected readonly SqlServerDBContext context;
        public SqlserverRepositoryBase(SqlServerDBContext _context)
        {
            context = _context;
        }


        #region insert

        public virtual int Add(TEntity obj)
        {
            context.Add(obj);
            return context.SaveChanges();
        }

        public virtual async Task<int> AddAsync(TEntity obj)
        {
            var entity = await context.AddAsync(obj);
            return context.SaveChanges();
        }
        public virtual async Task<TEntity> AddAsyncCallBack(TEntity obj)
        {
            var entity = await context.AddAsync(obj);
            context.SaveChanges();
            return entity.Entity;
        }

        public virtual int AddRange(ICollection<TEntity> obj)
        {
            context.AddRange(obj);
            return context.SaveChanges();
        }

        public virtual async Task<int> AddRangeAsync(ICollection<TEntity> entities)
        {
            await context.AddRangeAsync(entities);
            return await context.SaveChangesAsync();
        }
        #endregion insert

        #region select

        public virtual IQueryable<TEntity> GetAll()
        {
            return context.Set<TEntity>();
        }
        public virtual async Task<IEnumerable<TEntity>> GetAllAsync()
        {
            return await context.Set<TEntity>().ToListAsync();
        }

        public virtual async Task<TEntity> GetByIdAsync(object id)
        {
            return await context.Set<TEntity>().FindAsync(id);
        }

        public virtual TEntity GetById(object id)
        {
            return context.Set<TEntity>().Find(id);
        }

        public virtual IQueryable<TEntity> GetMany(Expression<Func<TEntity, bool>> where)
        {
            return context.Set<TEntity>().Where(where);
        }
        public virtual async Task<IEnumerable<TEntity>> GetManyAsync(Expression<Func<TEntity, bool>> where)
        {
            return await context.Set<TEntity>().Where(where).ToListAsync();
        }


        public bool HasEntity(out TEntity entity, Expression<Func<TEntity, bool>> where)
        {
            entity = context.Set<TEntity>().FirstOrDefault(where);
            if (entity != null)
            {
                return true;
            }
            return false;
        }

        #endregion select

        #region excute

        public virtual int Remove(TEntity obj)
        {
            context.Remove(obj);
            return context.SaveChanges();
        }
        public virtual async Task<int> RemoveRangeAsync(IEnumerable<TEntity> entities)
        {
            context.RemoveRange(entities);
            return await context.SaveChangesAsync();
        }

        public virtual int Update(TEntity obj)
        {
            context.Update(obj);
            return context.SaveChanges();
        }
        public virtual async Task<int> UpdateAsync(TEntity obj)
        {
            context.Update(obj);
            return await context.SaveChangesAsync();
        }

        public virtual async Task<int> UpdateRangeAsync(IEnumerable<TEntity> entities)
        {
            context.UpdateRange(entities);
            return await context.SaveChangesAsync();
        }



        public void Dispose()
        {
            context.Dispose();
            GC.SuppressFinalize(this);
        }
        #endregion excute
    }
}
